<template>
  <div class="image-uploader">
    <el-upload
      action
      accept="image/*"
      :http-request="handleImageUpload"
      :show-file-list="false"
      class="uploader-wrapper"
      v-loading="loading && canLoading"
      element-loading-custom-class="loading"
    >
      <div class="trigger" slot="trigger">
        <slot name="trigger">
          <el-button size="small" type="primary" class="upload-btn">选取图片</el-button>
        </slot>
      </div>
    </el-upload>
  </div>
</template>

<script>
import { upload } from "@/services";

export default {
  props: {
    canLoading: {
      type: Boolean,
      default() {
        return true;
      }
    }
  },
  data() {
    return {
      loading: false
    };
  },
  methods: {
    getImageSize(url) {
      return new Promise((resolve, reject) => {
        const image = new Image();
        image.src = url;
        image.onload = function() {
          resolve({
            width: this.width,
            height: this.height
          });
        };
        image.onerror = function(e) {
          reject(e);
        };
      });
    },
    async handleImageUpload({ file }) {
      const fd = new FormData();
      fd.set("file", file);
      this.loading = true;
      this.$emit("start");
      try {
        const data = await upload(fd);
        const size = await this.getImageSize(data);
        const url = `${data}#${size.width}x${size.height}`;
        this.$emit("done", url);
      } catch (err) {
        this.$notify({
          title: "图片上传错误",
          message: err.message,
          type: "error"
        });
        this.$emit("error", err);
      }
      this.loading = false;
    }
  }
};
</script>

<style lang="scss" scoped>
.image-uploader {
  display: inline-flex;
  .uploader-wrapper {
    display: inline-block;
    .upload-btn {
      display: block;
      margin-right: 10px;
    }
  }
  &::v-deep .loading {
    .el-loading-spinner {
      transform: translateY(-50%);
      margin-top: 0;
      height: 100%;
      svg {
        height: 100%;
      }
    }
  }
}
</style>
